import Singleton from "../Base/Singleton";
import { ApiMsgEnum } from "../Common";
import { PlayerManager } from "./PlayerMananger";
import { Room } from "./Room";

export class RoomManager extends Singleton {
  nextRoomId: number = 1;
  rooms: Set<Room> = new Set();
  idMapRoom: Map<number, Room> = new Map<number, Room>();

  static get Instance() {
    return super.GetInstance<RoomManager>();
  }

  syncRooms() {
    for (const player of PlayerManager.Instance.players) {
      player.connection.sendMsg(ApiMsgEnum.MsgRoomList, {
        list: this.getRoomsView(),
      });
    }
  }

  syncRoom(rid: number) {
    let room = this.idMapRoom.get(rid);
    if (room) {
      room.sync();
    }
  }

  closeRoom(rid: number) {
    if (this.idMapRoom.has(rid)) {
      const room = this.idMapRoom.get(rid);

      room.close();

      this.rooms.delete(room);
      this.idMapRoom.delete(room.id);
    }
  }

  createRoom(): Room {
    let room = new Room(this.nextRoomId++);

    this.rooms.add(room);
    this.idMapRoom.set(room.id, room);

    return room;
  }

  joinRoom(rid: number, uid: number) {
    let room = this.idMapRoom.get(rid);

    if (room) {
      room.join(uid);

      return room;
    }
  }

  leaveRoom(rid: number, uid: number) {
    let room = this.idMapRoom.get(rid);

    if (room) {
      room.leave(uid);
      // return room;
    }
  }

  startRoom(rid: number) {
    let room = this.idMapRoom.get(rid);

    if (room) {
      room.start();
      // return room;
    }
  }

  getRoomView({ id, players }: Room) {
    return {
      id,
      players: PlayerManager.Instance.getPlayersView(players),
    };
  }

  getRoomsView(rooms: Set<Room> = this.rooms) {
    return [...rooms].map((room) => this.getRoomView(room));
  }
}
